
Pull back the hood on the data and tech that informs EPM

At Cloudsmith, we believe that visibility, control, and automation are essential to securing your software supply chain. That’s why we built Enterprise Policy Management (EPM) as a programmable enforcement layer to let developers and security teams define and apply rules that govern the behaviour of packages within your repositories.
But how does it work under the hood?
This post lifts the curtain on the input data, technology stack, and policy lifecycle that drive Cloudsmith’s real-time, zero-trust decision engine - now extended to delay and block even the first download of non-compliant packages from upstream sources.
Rego is the policy language to manage Cloudsmith pipelines
At the core of EPM is Open Policy Agent (OPA) and its declarative language, Rego. OPA serves as the embedded decision engine, evaluating each package against the policies you define. Our CEO, Glenn Weinstein, already explained in a recent blog post why it makes sense to use open standard approaches that our end-users are already familiar with when managing artifact pipelines.
Cloudsmith wires OPA into the security scan phase of our package synchronisation pipeline. This phase processes every new package (whether uploaded directly or fetched from an upstream proxy) and applies the policies you’ve authored to determine the correct action to take (such as tagging, quarantining and blocking).
Input Schema provides the fuel for Policy Decisions
Policy logic in EPM is evaluated using a structured input document, passed to OPA. This document contains a complete snapshot of package context:
input.v0.package # Package metadata (filename, uploader, license, etc.)
input.v0.repository # Repo-level context (e.g., name)
input.v0.security_scan # Security scan results (vulnerabilities, CVSS scores)
To avoid surprises, we strongly recommend, users write policies against known, documented fields. Some examples can be seen on our Rego recipes page. Additionally, consider using the Simulation API to validate your logic against real package inputs. Finally, review the EPM Decision Logs to confirm your policy is matching as expected.
pkg := input.v0.package
endswith(pkg.filename, ".tar.gz")
not startswith(pkg.filename, "release-")
OPA won’t throw errors for undeclared fields, but it also won’t enforce your intent unless the data is actually there.
Visualising the policy lifecycle from request to enforcement
EPM policies are evaluated during specific phases of the package lifecycle: when a package is uploaded and when new vulnerability advisories are discovered.

The lifecycle of an EPM policy begins when a trigger fires - typically during the first security scan of a package as it synchronises into a repository. At this point, Cloudsmith compiles the package’s metadata, including structure, uploader, repository, all into a versioned input document for policy evaluation. Link to the Policy Triggers section of our docs.
In the Evaluation Phase, the input is matched against the rego-based policy using the OPA engine. Each policy defines a set of conditions including checks for security vulnerabilities, licensing violations, naming conventions, or custom business rules. Furthermore, Decision Logs are generated during the evaluation phase.
Once evaluation is complete, the Outcome Phase begins. If the policy evaluation results in a match, a predefined sequence of actions is executed in precedence order. These actions (such as AddPackageTags
, SetPackageState
) allow you to enforce outcomes like tagging and quarantining packages. Actions are defined separately and attached to policies, and each can be configured to run in sequence, with the option to stop further execution if the action is marked as terminal.
Importantly, each policy is evaluated independently. This means multiple policies can match and execute their actions in combination, unless one of them is marked as terminal, which halts further policy evaluation after it matches. Within a single policy, actions are executed in a deterministic order based on their precedence values, enabling precise control over outcomes like tagging or quarantining. This modular, layered approach allows you to compose nuanced lifecycle controls that align with your compliance and operational requirements.
Continuous security through CVE and EPSS feeds
Cloudsmith ingests vulnerability data from Common Vulnerabilities and Exposures (CVE) feeds. Each vulnerability includes standard metadata, such as CVSS v3 scores (via input.v0.security_scan
→ CVSS.V3Score
), the Status (such as fixed
and unfixed
), the published dates, descriptions, and the associated identifiers. These allow granular rule logic based on severity, age, fix availability and more.
Cloudsmith also supports querying EPSS (Exploit Prediction Scoring System) scores, which estimate the risk of a particular vulnerability to be exploited in the wild. These scores are embedded in each vulnerability record under vulnerability.epss.score
, enabling policies that trigger on the high likelihood of exploitation, as opposed to having a high CVSS score but is unlikely to be exploited as a real threat to an organisation.
Through Continuous Security, Cloudsmith refreshes both CVE and EPSS data regularly. The CVE database via Trivy database is refreshed approximately every 6 hours. Likewise, the EPSS data is updated every 24 hours. These automated feeds ensure that EPM policies act on fresh vulnerability insights - even after a package is ingested. Unlike classic vulnerability management, where scans soon get outdated, we keep artifact scan results up-to-date with the most relevant vulnerability feeds, allowing users to automate their responses if anything changes.
Knowing how Cloudsmith’s EPM combines static package metadata with dynamic vulnerability intelligence (such as CVE+CVSS+EPSS) refreshed continuously, it provides users with a robust foundation to craft nuanced, data-driven policies. You can, for example, block only recently published EPSS‑high CVEs with fixes, or create aging ramp policies using published date logic.
Policy enforcement at the point of ingress
With Cloudsmith's EPM, development teams can now enforce security and compliance policies before a package is ever downloaded, even on the very first request. Historically, packages fetched from upstream registries were cached and served immediately, with scanning and enforcement applied only after the first pull from upstream. This approach prioritised speed and developer velocity, but came with a trade-off: the earliest moment of ingress remained unchecked, allowing potentially vulnerable or non-compliant code into the development environment before any policy was applied.
Now, Cloudsmith introduces a "Block Until Scan" flow. While this isn't a unique flow to EPM, users can certainly use this flow within EPM. If a requested package isn’t already in your repository, Cloudsmith will pause the download until the package has been fetched, scanned, and evaluated against your defined policies. If it fails policy enforcement, either due to issues like high CVSS vulnerabilities, disallowed licenses, or missing metadata, the package will be blocked from being served entirely.

This approach changes Cloudsmith’s traditional model from reactive to proactive. It delivers true zero-trust enforcement from the outset, ensuring that no developer or CI pipeline can accidentally ingest unvetted software. Every package, whether direct or transitive, becomes subject to the same rigorous controls, ultimately helping organizations align with security frameworks like SLSA or NIST SSDF and pass compliance audits with confidence.
Anatomy of a Policy
All Cloudsmith EPM policies follow a consistent structure using Rego:
package cloudsmith
default match := false
match if count(reason) > 0
reason contains msg if {
pkg := input.v0.package
not pkg.license in {"MIT", "Apache-2.0"}
msg := sprintf("License '%s' is not approved", [pkg.license])
}
This logic fails the policy if the package’s license is not approved. In doing so it returns a clear, human-readable reason
message, which is helpful for debugging and explaining decisions. The standard structure sets default match := false
and sets match := true
if count(reason) > 0
, ensuring that matches are both explicit and traceable. Finally, it sets match := true
only when there are one or more policy violations. In this way, OPA decisions are deterministic, explainable, and fast, making them ideal for secure automation.
String Matching and Package Context
Rego provides powerful primitives for matching package names, filenames, tags, and other strings. Some real-world examples:
Enforce filename prefix:not startswith(pkg.filename, "internal-")
Checker uploader identity:pkg.uploader == "nigel-douglas"
Block missing metadata:not pkg.license
This flexibility allows you to enforce naming conventions, prevent shadow IT, or ensure metadata hygiene. If you are ever unsure about the supported fields that can be used in EPM Rego policies, check out the REST API documentation for Cloudsmith. Alternatively, Cloudsmith’s Ralph McTeggart created a useful ChatGPT Policy Advisor to better understand how to construct and validate policies on the fly.
Advanced example of blocking high-risk vulnerabilities with fixes
You can also craft more sophisticated rules that incorporate CVSS severity, EPSS risk, and whether a fix is available. This lets you enforce “smart blocking” - only quarantining packages that are both severe and exploitable, and that could be remediated.
package cloudsmith
default match := false
max_cvss := 8.0
min_epss := 0.5
match if count(reason) > 0
reason contains msg if {
some target in input.v0.security_scan
some vuln in target.Vulnerabilities
vuln.FixedVersion
vuln.Status == "fixed"
some _, cvss in vuln.CVSS
cvss.V3Score >= max_cvss
vuln.epss.score >= min_epss
msg := sprintf("Blocking CVE with CVSS %.1f, EPSS %.2f (fix available)", [cvss.V3Score, vuln.epss.score])
}
The above policy only matches vulnerabilities that already have a fix available. We explained in a previous blog post why this approach is important when tackling CVE tsunamis. This policy requires CVSS v3 score ≥ 8.0 (which is categorised as a HIGH severity). However, it also requires the EPSS score ≥ 0.5 (moderate to high likelihood of exploitation). As always, it should prevent high-risk downloads but also flags the issue with a descriptive message so DevOps teams can take action quickly.
By combining multiple data signals (severity, exploitability, fixability), you avoid noisy false positives and focus your policy enforcement on the vulnerabilities that truly matter. This balance helps developers ship securely, without drowning in alerts or blocking known harmless dependencies.
Summary
Cloudsmith’s EPM framework is driven by structured package metadata and enriched by real-time security scan outputs. This data forms the basis of each decision evaluation, allowing Rego-based policies to act deterministically based on concrete inputs such as CVSS scores, file counts, license data, and uploader identity. The integration of OPA ensures that every policy execution is reproducible, traceable, and fully customisable to suit the operational and security requirements of each workspace.
By embedding this decision logic at the point of package synchronisation, EPM supports early intervention and automated remediation, such as quarantining, tagging, or rejecting packages before they propagate through your CI/CD pipeline. The result is a policy engine that aligns tightly with your organisation’s compliance posture, operational norms, and internal trust boundaries, all without compromising the speed and automation you’ve come to expect from Cloudsmith.
More articles


Unlocking policy-as-code automation with Cloudsmith EPM

Pull back the hood on the data and tech that informs EPM

Compliance policies in EPM
By submitting this form, you agree to our privacy policy